package data.book;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import po.BookPO;
import po.CatagoryPO;

public class Catagory implements Serializable{
	private static final long serialVersionUID = 1L;
	private String name;
	private ArrayList<BookPO> bookList;
	private ArrayList<Catagory> subCatagory;
	private Catagory parentCatagory;
	
	public Catagory(String name,Catagory parentCatagory){
		this.name=name;
		this.parentCatagory=parentCatagory;
		bookList=new ArrayList<BookPO>();
		subCatagory=new ArrayList<Catagory>();		
	}
	
	public CatagoryPO createCatagotyPO(){		
		ArrayList<CatagoryPO> subCatagoryPO=new ArrayList<CatagoryPO>();
		for (int i = 0; i < subCatagory.size(); i++) {
			subCatagoryPO.add(subCatagory.get(i).createCatagotyPO());
		}
		CatagoryPO catagoryPO=new CatagoryPO(name,subCatagoryPO);
		
		return catagoryPO;
	}
	
	public Catagory searchCatagory(String catagoryName){
		if(!isRoot()){
			
			if(name.equals(catagoryName)){
				return this;
			}
			else{
				return searchCatagorySub(catagoryName);
			}
		}		
		else{
			//System.out.println(searchCatagorySub(catagoryName).getName());
			return searchCatagorySub(catagoryName);
		}				
		
	}
	
	private Catagory searchCatagorySub(String catagoryName){
		if(!hasSubCatagory()){
			return null;
		}
		Catagory catagory=null;
		
		for (int i = 0; i < subCatagory.size(); i++) {
			catagory=subCatagory.get(i).searchCatagory(catagoryName);
			if(catagory!=null){
				
				break;
			}
		}
		
		return catagory;
	}
	
	public HashMap<Integer,ArrayList<BookPO>> searchBook(Keyword keyword){
		HashMap<Integer, ArrayList<BookPO>> accuracyMap=new HashMap<Integer,ArrayList<BookPO>>();
		
		for (int i = 0; i < bookList.size(); i++) {
			int accuracy=keyword.getAccuracy(bookList.get(i).getName());
			if(accuracy!=0){
				mapPutBook(accuracyMap, accuracy, bookList.get(i));
			}
		}
		
		for (int i = 0; i < subCatagory.size(); i++) {
			HashMap<Integer,ArrayList<BookPO>> subAccuracyMap=subCatagory.get(i).searchBook(keyword);
			mergeMap(accuracyMap, subAccuracyMap);
		}
		
		return accuracyMap;
	}
	
	private void mergeMap(HashMap<Integer, ArrayList<BookPO>> containMap
			,HashMap<Integer, ArrayList<BookPO>> operateMap){
		Iterator<Integer> iterator=operateMap.keySet().iterator();
		while(iterator.hasNext()){
			int key=iterator.next();
			if(containMap.containsKey(key)){
				containMap.get(key).addAll(operateMap.get(key));
			}
			else{
				containMap.put(key, operateMap.get(key));
			}
		}
	}
	
	private void mapPutBook(HashMap<Integer, ArrayList<BookPO>> accuracyMap,
			int accuracy,BookPO book){
		if(accuracyMap.containsKey(accuracy)){
			accuracyMap.get(accuracy).add(book);
		}
		else{
			ArrayList<BookPO> list=new ArrayList<BookPO>();
			list.add(book);
			accuracyMap.put(accuracy, list);
		}
	}
	
	public void renameTo(String newName){
		this.name=newName;
	}
	
	public Catagory getParent(){
		return parentCatagory;
	}
	
	public boolean addCatagory(String catagoryName){
		return subCatagory.add(new Catagory(catagoryName, this));
	}
	
	public boolean deleteCatagory(Catagory catagory){
		return subCatagory.remove(catagory);
	}
	
	public boolean addBook(BookPO book){
		return bookList.add(book);
	}
	
	public boolean deleteBook(BookPO book){
		for (BookPO i:bookList) {
			if(i.isSame(book)){
				return bookList.remove(i);
			}
		}
		return false;
	}
	
	public String getName(){
		return name;
	}
	
	public boolean hasSubCatagory(){
		return subCatagory.size()!=0;
	}
	
	public Iterator<Catagory> getSubCatagory(){
		return subCatagory.listIterator();
	}
	
	public Iterator<BookPO> getBookList(){
		return bookList.listIterator();
	}
	
	public boolean isRoot(){
		return name==null;
	}
}
